/************************************
 * Package: RGcpp					*
 * Authors: Rui Eduardo Gouveia Gil	*
 * Date: 2010						*
 ************************************/
#include "rgcpp/net/ssl/SSLServerSocket.h"

namespace rgcpp
{

std::string SSLServerSocket::password2check = "";

SSLServerSocket::SSLServerSocket(SSLContext* sslContext) : TCPServerSocket()
{
	this->sslContext = sslContext;
}

SSLServerSocket::SSLServerSocket(SSLContext* sslContext, const unsigned short port) : TCPServerSocket(port)
{
	this->sslContext = sslContext;
}

SSLServerSocket::SSLServerSocket(SSLContext* sslContext, const IPAddress& ipAddress) : TCPServerSocket(ipAddress)
{
	this->sslContext = sslContext;
}

SSLServerSocket::~SSLServerSocket()
{

}

SSLSocket* SSLServerSocket::accept()
{
	boost::mutex::scoped_lock lock(mut);

	fd_set fdList;

	FD_ZERO(&fdList);
	FD_SET(socketAccept, &fdList);

	int value;
	struct timeval timeout = this->timeout;
	do
	{
		if(!timeout.tv_usec && !timeout.tv_sec)
			value = select(socketAccept+1,&fdList,NULL,NULL,NULL);
		else
			value = select(socketAccept+1,&fdList,NULL,NULL,&timeout);
	}while(value == -1&& errno == EINTR);

	if(value == 0)
	{
		Throw(SocketException(std::string("Error ssl server socket - Timeout exception")));
	}
	else if(value == -1)
	{
		Throw(SocketException(std::string("Error ssl server socket - ")+strerror(errno)));
	}

	if(this->releaseForced)
		return NULL;

	// Open up new connection
	struct sockaddr_in addr;
	int len = sizeof(addr);

#ifdef _WIN32
	int client = ::accept(socketAccept,(struct sockaddr *)&addr,&len);
#else
	int client = ::accept(socketAccept,(struct sockaddr *)&addr,(socklen_t *)&len);
#endif

	if(client == -1)
	{
		Throw(SocketException(std::string("Invalid socket file descriptor - ")+strerror(errno)));
	}

	return new SSLSocket(sslContext,client);
}

}
